<?php
/**
 * 自定义session 管理
 * Created by PhpStorm.
 * User: TS
 * Date: 2017/4/4
 * Time: 20:25
 */
namespace core;

use core\session\driver\DbSession;
use core\session\SessionInterface;

class Session {

    const SESSION_NAME = 's_id';

    const GC_TIME = 3600;

    protected $session;

    protected static $instance;


    public function __construct(SessionInterface $session)
    {
        $this->session = $session;
    }

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new static( new DbSession );
        }
        self::$instance->start();
        return self::$instance;
    }

    /**
     * 开启session
     * @return bool
     */
    public function start()
    {
        if (! Cookie::get(self::SESSION_NAME)) {
            Cookie::set(self::SESSION_NAME, md5(createGuid()));
            $this->gc();
            $this->session->write(Cookie::get(self::SESSION_NAME), $this->setData());
        }
        return true;
    }

    /**
     * 删除session
     * @return bool
     */
    public function destroy()
    {
        return $this->session->destroy(Cookie::get(self::SESSION_NAME));
    }

    /**
     * 获取session
     * @param null $key
     * @return mixed|null
     */
    public function get($key = null)
    {
        $data = self::getData($this->session->read(Cookie::get(self::SESSION_NAME)));
        if (!empty($key)) $data = isset($data[$key]) ? $data[$key] : null;
        return $data;
    }

    /**
     * 设置session
     * @param $key
     * @param $value
     * @return bool
     */
    public function set($key, $value)
    {
        $data = self::getData($this->session->read(Cookie::get(self::SESSION_NAME)));
        $data[$key] = $value;
        return $this->session->write(Cookie::get(self::SESSION_NAME), self::setData($data));
    }

    /**
     * 工厂回收
     * @return bool
     */
    public function gc()
    {
        return $this->session->gc(self::GC_TIME);
    }

    /**
     * 设置data
     * @param array $data
     * @return string
     */
    protected static function setData($data = [])
    {
        return serialize($data);
    }

    /**
     * 读取data
     * @param $value
     * @return mixed
     */
    protected static function getData($value)
    {
        return unserialize($value);
    }
}